package com.company.service.impl;

import com.company.service.ICacheService;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * Created by tu on 2017/7/3.
 */
@Service
public class RedisServiceImpl implements ICacheService {

  private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);
  @Autowired
  private JedisPool jedisPool;

  @Override
  public String set(String key, String value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      String code = jedis.set(key, value);
      logger.info("jedis.set({}, {}), result:{}", key, value, code);

      return code;
    } catch (Exception e) {
      logger.error("jedis.set({}, {})", key, value);
    } finally {
      close(jedis);
    }
    return null;
  }

  @Override
  public String setex(String key, int seconds, String value) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      String code = jedis.setex(key, seconds, value);
      logger.info("jedis.setex({}, {}, {}), result:{}", key, seconds, value, code);
      return code;
    } catch (Exception e) {
      logger.error("jedis.setex({}, {}, {})", key, seconds, value);
    } finally {
      close(jedis);
    }
    return null;
  }

  @Override
  public String get(String key) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      String bulk = jedis.get(key);
      logger.info("jedis.get({}), result:{}", key, bulk);
      return bulk;
    } catch (Exception e) {
      logger.error("jedis.get({})", key);
    } finally {
      close(jedis);
    }
    return null;
  }

  @Override
  public Long del(String... keys) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long code = jedis.del(keys);
      logger.info("jedis.del({}), result:{}", keys, code);
      return code;
    } catch (Exception e) {
      logger.error("jedis.del({})", keys);
    } finally {
      close(jedis);
    }
    return 0l;
  }

  @Override
  public Long del(String key) {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long code = jedis.del(key);
      logger.info("jedis.del({}), result:{}", key, code);
      return code;
    } catch (Exception e) {
      logger.error("jedis.del({})", key);
    } finally {
      close(jedis);
    }
    return 0l;
  }

  @Override
  public Long delPattern(String pattern) {
    Set<String> keys = keys(pattern);
    Long count = 0L;
    Iterator<String> it = keys.iterator();
    while (it.hasNext()) {
      String keyStr = it.next();
      count += del(keyStr);
    }
    logger.info("delPattern({}), result:{}", pattern, count);
    return count;
  }

  @Override
  public Long exists(String... keys) {

    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long code = jedis.exists(keys);
      logger.info("jedis.exists({}), result:{}", keys, code);
      return code;
    } catch (Exception e) {
      logger.error("jedis.exists({})", keys);
    } finally {
      close(jedis);
    }
    return 0l;
  }

  @Override
  public Boolean exists(String key) {

    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Boolean code = jedis.exists(key);
      logger.info("jedis.exists({}), result:{}", key, code);
      return code;
    } catch (Exception e) {
      logger.error("jedis.exists({})", key);
    } finally {
      close(jedis);
    }
    return Boolean.FALSE;
  }

  /**
   * 获取keys
   *
   * @return Multi bulk reply
   */
  @Override
  public Set<String> keys(String pattern) {
    Set<String> keys = new HashSet<>();
    Jedis connection = jedisPool.getResource();
    try {
      keys.addAll(connection.keys(pattern));
    } catch (Exception e) {
      logger.error("Getting keys error: {}", e);
    } finally {
      close(connection);
    }
    return keys;
  }

  /**
   * 释放jedis资源
   */
  private void close(Jedis jedis) {
    if (jedis != null) {
      jedis.close();
    }
  }
}